
package tech.yunland.shop.domain.service;

import com.moyuer.bsf.common.Convertor;
import com.moyuer.bsf.domain.model.HqlArgs;
import com.moyuer.bsf.domain.model.Organ;
import org.apache.commons.lang3.StringUtils;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import tech.yunland.shop.domain.dao.GoodsDao;
import tech.yunland.shop.domain.dao.SNGenerator;
import tech.yunland.shop.domain.dao.StoreBillDao;
import tech.yunland.shop.domain.dao.StoreBillEntryDao;
import tech.yunland.shop.domain.model.*;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.*;

/**
 * 出入库单
 */
@Service
public class StoreBillService {

    @Autowired
    private StoreBillDao storeBillDao;

    @Autowired
    private StoreBillEntryDao storeBillEntryDao;

    @Autowired
    private SNGenerator snGenerator;

    @Autowired
    private GoodsDao goodsDao;

    @Autowired
    private FinanceBillService financeBillService;

    @Autowired
    private GoodsStockService goodsStockService;

    @Autowired
    private PurchaseBillService purchaseBillService;

    @Autowired
    private AllotBillServiceImpl allotBillServiceImpl;

    /**
     * 保存单据
     *
     * @param storeBill
     */
    public void saveStore(StoreBill storeBill) {


        Integer direction = storeBill.getDirection();
        if (storeBill.getBiz_type().intValue() == 0) {
            if (direction.intValue() == 1) {
                storeBill.setBiz_type(Integer.valueOf(1));
            } else {
                storeBill.setBiz_type(Integer.valueOf(-1));
            }
        }

        storeBill.setState(Integer.valueOf(0));//新增的出入库单，全部为暂存状态
        storeBillDao.saveOrUpdate(storeBill);

        Set<StoreBillEntry> entries = new HashSet<>();

        Iterator<StoreBillEntry> iterator = storeBill.getEntries().iterator();

        while (iterator.hasNext()) {

            StoreBillEntry entry = iterator.next();

            String goods_id = entry.getGoods().getId();

            //storeBillDao.saveOrUpdate(storeBill);
            Goods goods = goodsDao.get(goods_id);

            if (goods == null) {
                throw new RuntimeException("选择商品异常：【您未选择商品或一次性选择多个商品】");
            }

            if (goods.getKindCode().intValue() != 10) { //出入库单只保存实物
                throw new RuntimeException(goods.getName() + "为非实物不能保存");
            }

            BigDecimal goodsPrice = goods.getPrice();

            BigDecimal quantity = entry.getQuantity();

            if (quantity.intValue() <= 0) {
                throw new RuntimeException("商品数量应至少为1");
            }

            if (direction < 0) { //判断为出库的情况
//                boolean hasUsed = goodsStockService.isHasUsed(quantity, goods_id, storeBill.getOrganId());
//                if (!hasUsed) {
//                 //   throw new RuntimeException(goods.getName() + "库存不足");
//                }
            }

            StoreBillEntry storeBillEntry = new StoreBillEntry();
            storeBillEntry.setGoods(goods);
            storeBillEntry.setQuantity(quantity);
            BigDecimal amount = goodsPrice.multiply(quantity);
            storeBillEntry.setAmount(amount);
            storeBillEntry.setPrice(goodsPrice);
            storeBillEntry.setState(0);//现在认为状态为0的是未复核状态 也就是在途
            storeBillEntry.setOwner(storeBill);
            //保存出库单分录
            storeBillEntryDao.save(storeBillEntry);

            entries.add(storeBillEntry);

        }
        //更新库存
        storeBill.setEntries(entries);


        this.updateStock(storeBill);
    }

    /**
     * 读取出入库单分录
     *
     * @param id
     * @return
     */

    public StoreBillEntry getEntry(String id) {
        return storeBillEntryDao.get(id);
    }

    /**
     * 根据id查询
     *
     * @param id
     * @return
     */
    public StoreBill getStore(String id) {

        return storeBillDao.get(id);
    }

    /**
     * 根据id 删除单据信息
     *
     * @param id
     */
    public void deleteStore(String id) {
        StoreBill storeBill = storeBillDao.get(id);
        if (storeBill != null && storeBill.getState() != -1) {

            if (storeBill.getState().intValue() == 3) {
                throw new RuntimeException("单据已执行,不可删除");
            }

            storeBill.setState(-1);

            this.updateStock(storeBill, false, true);
        } else {
            throw new RuntimeException("该单据已经删除");
        }
        storeBillDao.update(storeBill);
    }

    /**
     * 根据id删除分录
     *
     * @param id
     */
    public void deleteStoreEntry(String id) {
        StoreBillEntry storeBillEntry = storeBillEntryDao.get(id);

        StoreBill storeBill = storeBillEntry.getOwner();

        if (storeBill != null && storeBill.getState().intValue() == 3) {
            throw new RuntimeException("单据已执行,不可修改");
        }

        if (storeBill != null && storeBill.getState().intValue() == -2) {
            this.updateState(storeBill.getId(), 0);
        }

        if (storeBillEntry != null && storeBillEntry.getState() != -1) {
            storeBillEntry.setState(-1);
        } else {
            throw new RuntimeException("该商品已经删除");
        }
        storeBillEntryDao.update(storeBillEntry);

        GoodsStock stock = new GoodsStock();
        stock.setGoods(storeBillEntry.getGoods());
        stock.setOrgan(storeBill.getOrgan());
        stock.setStoreNum(storeBillEntry.getQuantity().doubleValue() * -1);
        if (storeBill.getDirection().intValue() > 0) {
            stock.setState(Integer.valueOf(-1));
        } else {
            stock.setState(Integer.valueOf(0));
        }
        goodsStockService.saveOrUpdateStock(stock);
    }

    /**
     * 保存分录
     *
     * @param billEntry
     */
    public void saveEntry(StoreBillEntry billEntry) {
        StoreBillEntry storebillEntry = new StoreBillEntry();
        BigDecimal quantity = billEntry.getQuantity();

        if (quantity.intValue() <= 0) {
            throw new RuntimeException("商品数量应至少为1");
        }

        Integer state = billEntry.getState();
        String goods_id = billEntry.getGoods().getId();
        Goods goods = goodsDao.get(goods_id);

        if (goods == null) {
            throw new RuntimeException("选择商品异常：【您未选择商品或一次性选择多个商品】");
        }

        if (goods.getKindCode().intValue() != 10) { //出入库单只保存实物
            throw new RuntimeException(goods.getName() + "为非实物不能保存");
        }

        BigDecimal price = goods.getPrice();
        BigDecimal amount = price.multiply(quantity);
        storebillEntry.setQuantity(quantity);
        storebillEntry.setState(state);
        storebillEntry.setPrice(price);
        storebillEntry.setAmount(amount);
        storebillEntry.setGoods(goods);
        String ownerId = billEntry.getOwner().getId();

        StoreBill storeBill = storeBillDao.get(ownerId);
//        if (storeBill.getEntrySize() >= 1) {
//            throw new RuntimeException("此单据不为空");
//        }

        storebillEntry.setOwner(storeBill);
        storeBillEntryDao.save(storebillEntry);


        if (storeBill != null && storeBill.getState().intValue() == -2) {
            this.updateState(ownerId, 0);
        }

        GoodsStock stock = new GoodsStock();
        stock.setGoods(storebillEntry.getGoods());
        stock.setOrgan(storeBill.getOrgan());
        stock.setStoreNum(storebillEntry.getQuantity().doubleValue());
        if (storeBill.getDirection().intValue() > 0) {
            stock.setState(Integer.valueOf(-1));
        } else {
            stock.setState(Integer.valueOf(0));
        }
        goodsStockService.saveOrUpdateStock(stock);
    }


    /**
     * 修改分录
     *
     * @param entry
     */
    public void updateEntry(StoreBillEntry entry) {
        StoreBillEntry storebillEntry = storeBillEntryDao.get(entry.getId());

        BigDecimal _quantity = storebillEntry.getQuantity();//原来的商品数量
        Goods _goods = storebillEntry.getGoods(); //原来的商品

        BigDecimal quantity = entry.getQuantity(); //更改的商品数量

        if (quantity.intValue() <= 0) {
            throw new RuntimeException("商品数量应至少为1");
        }

        Integer state = entry.getState();
        String goods_id = entry.getGoods().getId();
        Goods goods = goodsDao.get(goods_id);

        if (goods == null) {
            throw new RuntimeException("选择商品异常：【您未选择商品或一次性选择多个商品】");
        }

        Integer kindCode = goods.getKindCode();
        if (kindCode != 10) {
            throw new RuntimeException(goods.getName() + "为非实物不能保存！");
        }

        BigDecimal price = goods.getPrice();
        BigDecimal amount = price.multiply(quantity);

        storebillEntry.setQuantity(quantity);
        storebillEntry.setState(state);
        storebillEntry.setPrice(price);
        storebillEntry.setAmount(amount);
        storebillEntry.setGoods(goods);
        String ownerId = entry.getOwner().getId();
        StoreBill storeBill = storeBillDao.get(ownerId);
        storebillEntry.setOwner(storeBill);

        storeBillEntryDao.update(storebillEntry);

        Integer direction = storeBill.getDirection().intValue();

//        if (storeBill != null && storeBill.getState().intValue() == 1) {
//            throw new RuntimeException("该单据正在审批");
//        }

        if (storeBill != null && storeBill.getState().intValue() == -2) {
            this.updateState(ownerId, 0);
        }

        if (_goods != null && _goods.getId().equals(goods_id)) { //判断更改后的分录是否改变了商品
            GoodsStock stock = new GoodsStock();
            stock.setGoods(storebillEntry.getGoods());
            stock.setOrgan(storeBill.getOrgan());
            stock.setStoreNum(quantity.subtract(_quantity).doubleValue());
            if (storeBill.getDirection().intValue() > 0) {
                stock.setState(Integer.valueOf(-1));
            } else {
                stock.setState(Integer.valueOf(0));
            }

            if (direction < 0) {
                boolean hasUsed = goodsStockService.isHasUsed(quantity.subtract(_quantity), goods_id, storeBill.getOrganId());
                if (!hasUsed) {
                    throw new RuntimeException(goods.getName() + "库存不足");
                }
            }

            goodsStockService.saveOrUpdateStock(stock);
        } else {
            //加上新的商品库存

            if (direction < 0) { //判断为出库的情况
                boolean hasUsed = goodsStockService.isHasUsed(quantity, goods_id, storeBill.getOrganId());
                if (!hasUsed) {
                    throw new RuntimeException(goods.getName() + "库存不足");
                }
            }
            GoodsStock stock1 = new GoodsStock();
            stock1.setGoods(storebillEntry.getGoods());
            stock1.setOrgan(storeBill.getOrgan());
            stock1.setStoreNum(quantity.doubleValue());
            if (storeBill.getDirection().intValue() > 0) {
                stock1.setState(Integer.valueOf(-1));
            } else {
                stock1.setState(Integer.valueOf(0));
            }
            goodsStockService.saveOrUpdateStock(stock1);

            //减去旧的商品库存
            GoodsStock stock2 = new GoodsStock();
            stock2.setGoods(_goods);
            stock2.setOrgan(storeBill.getOrgan());
            stock2.setStoreNum(_quantity.multiply(BigDecimal.valueOf(-1L)).doubleValue());
            if (storeBill.getDirection().intValue() > 0) {
                stock2.setState(Integer.valueOf(-1));
            } else {
                stock2.setState(Integer.valueOf(0));
            }
            goodsStockService.saveOrUpdateStock(stock2);
        }

    }

    public StoreBillEntry getEntryInfo(String id) {
        return storeBillEntryDao.get(id);
    }

    //------------------出入库单---------------------

    private HqlArgs getStoreBillHqlArgs(String param, Integer direction, List<String> organIds, List<Integer> states) {
        param = StringUtils.trimToEmpty(param);
        if (organIds == null || organIds.size() < 1) {
            throw new RuntimeException("权限不足");
        }
        HashMap<String, Object> args = new HashMap<>();

        String hql = "FROM StoreBill s WHERE s.state<>-1 AND s.entries.size>0 AND EXISTS (SELECT e.id FROM s.entries e WHERE e.state<>-1)";

        if (direction != null) {
            hql += " AND s.direction = :direction";
            args.put("direction", direction);
        }


        hql += " AND s.organ.id in :organIds";
        args.put("organIds", organIds);

        if (states != null) {
            if (states.size() == 1) {
                hql += " AND s.state = :state";
                args.put("state", states.get(0));
            } else {
                hql += " AND s.state in :states";
                args.put("states", states);
            }
        }


        if (StringUtils.isNotBlank(param)) {
            hql += " AND (s.sn LIKE :param OR";
            hql += " (CASE s.biz_type WHEN '-1' THEN '普通出库' WHEN '-2' THEN '销售出库' WHEN '1' THEN '普通入库' WHEN '2' THEN '采购入库' END) LIKE :param OR";
            hql += " (CASE s.state WHEN '0' THEN '暂存' WHEN '-2' THEN '未通过' WHEN '1' THEN '审批中' WHEN '2' THEN '通过' WHEN '3' THEN '复核' END) LIKE :param OR ";
            hql += " s.creator.name LIKE :param OR";
            hql += " EXISTS (SELECT e.id FROM s.entries e WHERE e.state=1 AND (e.goods.name LIKE :param OR e.goods.spell LIKE :param)))";
            args.put("param", "%" + param + "%");
        }

        return new HqlArgs(hql, args);
    }

    /**
     * 查询所有单据
     *
     * @param organIds 可视机构
     * @param page
     * @param rows
     * @param states
     * @return
     */
    public List<StoreBill> getAllBill(String param, List<String> organIds, Integer direction,
                                      Integer page, Integer rows, List<Integer> states) {
        HqlArgs hqlArgs = getStoreBillHqlArgs(param, direction, organIds, states);
        String s = hqlArgs.getHql() + " ORDER BY s.bizdate DESC,s.sn DESC";
        List<StoreBill> storeBills = storeBillDao.findByNamedParam(s, page, rows, hqlArgs.getArgs());
        return storeBills;
    }

    /**
     * 获取所有单据数量
     *
     * @param param
     * @param organIds  可视机构
     * @param direction
     * @param states
     * @return
     */
    public Integer getAllBillSize(String param, List<String> organIds, Integer direction, List<Integer> states) {
        HqlArgs hqlArgs = getStoreBillHqlArgs(param, direction, organIds, states);
        return (int) storeBillDao.getCount(hqlArgs.getHql(), hqlArgs.getArgs());
    }

    //------------出入库下的分录--------

    /**
     * 查询单个出入库单的详细分录
     *
     * @param ownerId
     * @param page
     * @param rows
     * @return
     */
    public List<StoreBillEntry> getStoreBillEntry(String ownerId, Integer page, Integer rows) {
        String hql = "FROM StoreBillEntry e  WHERE e.state>=0 AND e.owner.id = ? ORDER BY e.amount DESC";
        List<StoreBillEntry> storeBillEntries = storeBillEntryDao.find(hql, page, rows, ownerId);
        return storeBillEntries;
    }

    public Integer getStoreBillEntrySize(String ownerId) {
        String hql = "FROM StoreBillEntry e  WHERE e.state>=0 AND e.owner.id = ? ORDER BY e.amount DESC";
        List<StoreBillEntry> storeBillEntries = storeBillEntryDao.find(hql, ownerId);
        return storeBillEntries.size();
    }

    /**
     * 更改状态
     *
     * @param storeId
     * @param state
     */
    public void updateState(String storeId, Integer state) {
        StoreBill storeBill = storeBillDao.get(storeId);
        if (storeBill != null) {
            if (storeBill.getState().intValue() == 3) {
                throw new RuntimeException("该单据不能重复执行");
            }
            storeBill.setState(state);
            storeBillDao.update(storeBill);

            if (state.intValue() == 3) {
                this.updateStock(storeBill, true, false);
            }
        } else {
            throw new RuntimeException("单据异常");
        }
    }

    /**
     * 更新库存
     *
     * @param storeBill
     * @param isAppled   是否经过流程审批步骤
     * @param isApproved 是否申请通过
     */
    public void updateGoodsStock(StoreBill storeBill, boolean isAppled, boolean isApproved) {

        Integer bizType = storeBill.getBiz_type();

        if (storeBill != null) {
            Organ organ = storeBill.getOrgan();
            Iterator<StoreBillEntry> iterator = storeBill.getEntries().iterator();
            while (iterator.hasNext()) {
                StoreBillEntry entry = iterator.next();

                Goods goods = entry.getGoods();
                BigDecimal quantity = entry.getQuantity();

                GoodsStock stock = new GoodsStock();
                stock.setGoods(goods);
                stock.setOrgan(organ);

                if (!isAppled) { //如果不是由审批完成的

                    //如果为销售出库 则真实库存直接去除相应数量
                    stock.setStoreNum(bizType.intValue() == -2 ? quantity.multiply(BigDecimal.valueOf(-1)).doubleValue() : quantity.doubleValue());

                    switch (bizType.intValue()) {
                        case -2: //销售出库
                            stock.setState(Integer.valueOf(1));
                            break;
                        case -1://普通出库
                            stock.setState(Integer.valueOf(0));//冻结
                            break;
                        case 1:
                            stock.setState(Integer.valueOf(-1));//在途
                            break;
                        case 2:
                            stock.setState(Integer.valueOf(1));
                            break;
                    }
                } else {
                    if (isApproved) {//是否审批通过

                        stock.setStoreNum(quantity.multiply(BigDecimal.valueOf(-1)).doubleValue());
                        if (bizType.intValue() == 1) { //普通入库
                            stock.setState(Integer.valueOf(-1));
                            goodsStockService.saveOrUpdateStock(stock);
                            stock.setStoreNum(quantity.doubleValue());
                        } else if (bizType.intValue() == -1) { //普通出库
                            stock.setState(Integer.valueOf(0));
                            goodsStockService.saveOrUpdateStock(stock);
                            stock.setStoreNum(quantity.multiply(BigDecimal.valueOf(-1)).doubleValue());
                        }
                        stock.setState(Integer.valueOf(1));

                    } else {
                        stock.setStoreNum(quantity.multiply(BigDecimal.valueOf(-1)).doubleValue());
                        if (bizType.intValue() == 1) { //普通入库
                            stock.setState(Integer.valueOf(-1));
                        } else if (bizType.intValue() == -1) { //普通出库
                            stock.setState(Integer.valueOf(0));
                        }
                    }

                }

                goodsStockService.saveOrUpdateStock(stock);
            }
        }

    }

    /**
     * 更新库存
     */

    private void updateStock(StoreBill storeBill) {
        Integer type = storeBill.getBiz_type();//
        String organId = storeBill.getOrganId();
        Date currentDate = new Date();
        String today = Convertor.formatDate(currentDate, "yyyy-MM-dd");
        if (type > 0) {//该单据为入库
            for (StoreBillEntry billEntry : storeBill.getEntries()) {
                String goodsId = billEntry.getGoodsId();
                Double nums = billEntry.getQuantity().doubleValue();
                Boolean flag = this.isHasToday(goodsId, organId, today);
                if (flag) {//表示指定商品在当前仓库的今天已经有录入数据了我们更新就行了
                    this.updateStoreBegin(organId, goodsId, nums, today);
                } else {//否则插入
                    this.insertStore(organId, goodsId, nums);
                }


            }
        } else if (type < 0) {//为出库
            for (StoreBillEntry billEntry : storeBill.getEntries()) {
                String goodsId = billEntry.getGoodsId();
                Double nums = billEntry.getQuantity().doubleValue();
                Boolean flag = this.isHasToday(goodsId, organId, today);
                if (flag) {//表示指定商品在当前仓库的今天已经有录入数据了我们更新就行了
                    this.updateStoreBeginOut(organId, goodsId, nums, today);
                } else {//否则插入
                    this.insertStoreOut(organId, goodsId, nums);
                }

            }
        }


    }

    private void insertStoreOut(String organId, String goodsId, Double nums) {
        Session csession = storeBillEntryDao.getSession();
        SQLQuery sqlQuery = null;
        String iSql = "insert into goods_store (organ_id,goods_id,freeze_up) VALUES (?,?,?)";
        sqlQuery = csession.createSQLQuery(iSql);
        sqlQuery.setString(0, organId);
        sqlQuery.setString(1, goodsId);
        sqlQuery.setDouble(2, nums);

        sqlQuery.executeUpdate();
    }

    private void updateStoreBeginOut(String organId, String goodsId, Double nums, String today) {
        Session csession = storeBillEntryDao.getSession();
        SQLQuery sqlQuery = null;
        String updateSql = "update goods_store \n" +
                "set freeze_up = freeze_up+? \n" +
                "where to_char(create_time,'yyyy-mm-dd') =?" +
                "\n and organ_id = ?" +
                "\n and goods_id = ?";
        sqlQuery = csession.createSQLQuery(updateSql);
        sqlQuery.setDouble(0, nums);

        sqlQuery.setString(1, today);
        sqlQuery.setString(2, organId);
        sqlQuery.setString(3, goodsId);
        sqlQuery.executeUpdate();
    }

    /**
     * 刚生成入库单时的仓库保存逻辑
     *
     * @param organId
     * @param goodId
     * @param nums
     * @param today
     */
    private void updateStoreBegin(String organId, String goodId, Double nums, String today) {
        Session csession = storeBillEntryDao.getSession();
        SQLQuery sqlQuery = null;
        String updateSql = "update goods_store  " +
                " set in_transit = in_transit+? " +
                "where to_char(create_time,'yyyy-mm-dd') =?" +
                "\n and organ_id = ?" +
                "\n and goods_id = ?";
        sqlQuery = csession.createSQLQuery(updateSql);
        sqlQuery.setDouble(0, nums);

        sqlQuery.setString(1, today);
        sqlQuery.setString(2, organId);
        sqlQuery.setString(3, goodId);
        sqlQuery.executeUpdate();
    }

    /**
     * 更新库存
     *
     * @param storeBill  单据
     * @param isExecuted 是否已经执行
     * @param isDelete   是否执行删除
     */
    private void updateStock(StoreBill storeBill, boolean isExecuted, boolean isDelete) {

        Integer biz_type = storeBill.getBiz_type(); //-1 普通出库 -2 销售出库  1：普通入库 2：采购入库

        Set<StoreBillEntry> entries = storeBill.getEntries();


        for (StoreBillEntry entry : entries) {

            if (entry != null && entry.getState() != null && entry.getState().intValue() != -1) {

                GoodsStock stock = new GoodsStock();
                stock.setOrgan(storeBill.getOrgan());
                Goods goods = entry.getGoods();
                BigDecimal quantity = entry.getQuantity();
                stock.setGoods(goods);

                if (!isDelete) { //是否执行删除命令
                    stock.setStoreNum(quantity.doubleValue());
                } else {
                    stock.setStoreNum(quantity.multiply(BigDecimal.valueOf(-1L)).doubleValue());
                }

                if (isExecuted) {
                    //更新已启用的库存
                    if (biz_type.intValue() < 0) { //若为出库，减
                        stock.setStoreNum(quantity.multiply(BigDecimal.valueOf(-1L)).doubleValue());
                    }
                    stock.setState(Integer.valueOf(1));
                    goodsStockService.saveOrUpdateStock(stock);

                    //减去原[在途/冻结]的库存
                    stock.setStoreNum(quantity.multiply(BigDecimal.valueOf(-1L)).doubleValue());
                }

                if (biz_type.intValue() > 0) {//说明是入库
                    //在途 -1
                    stock.setState(Integer.valueOf(-1));
                } else if (biz_type.intValue() < 0) {//说明是出库
                    //冻结 0
                    stock.setState(Integer.valueOf(0));
                }
                goodsStockService.saveOrUpdateStock(stock);
            }

        }

    }

    /**
     * 修改单据备注
     *
     * @param id
     * @param remark
     */
    public void updateBillRemark(String id, String remark) {
        StoreBill storeBill = storeBillDao.get(id);
        if (storeBill != null) {
            storeBill.setRemark(remark);
            storeBillDao.update(storeBill);
        }
    }

    /**
     * 执行复核操作
     *
     * @param entryIds  待复核的分录IDs
     * @param inOrganId 收货仓库
     * @param numbers   待复核数量
     * @return
     * @author 李珂
     */
    public Boolean executedByEntryId(List<String> entryIds, String inOrganId, List<Double> numbers) {


        String ids = StringUtils.join(entryIds, "','");
        String sql = "select\n" +
                "   be.owner_id as billid  \n" +
                "  ,be.goods_id as gid    \n" +
                "  ,be.quantity  \n" +
                "  ,be.store_id as sid   " +
                "  ,be.id entryid  " +
                "  ,bs.organ_id as oid   " +
                "  ,be.state     \n" +
                "\n" +
                "from    bill_store_entry be,\n" +
                "              bill_store bs\n" +
                "where\n" +
                "       be.id in('" + ids + "') \n" +
//                "       and bs.organ_id = '" + inOrganId + "'" +
                "       and be.state = 0  " +
                "       and be.owner_id = bs.id\n";

        //得到当前机构下
        List<Map<String, Object>> storeBillEntrys = storeBillEntryDao.findBySQL(sql);
        if (!ObjectUtils.isEmpty(storeBillEntrys)) {
            for (int i = 0; i < storeBillEntrys.size(); i++) {
                //for(Map<String,Object> billEntry:storeBillEntrys){
                Map<String, Object> billEntry = storeBillEntrys.get(i);
                String goodsId = (String) billEntry.get("gid");
                String entryId = (String) billEntry.get("entryid");

                int i1 = entryIds.indexOf(entryId);
                Double nums = numbers.get(i1);

                Double quantity = ((BigDecimal) billEntry.get("quantity")).doubleValue();
                String billOrganId = (String) billEntry.get("oid");
                String billId = (String) billEntry.get("billid");

                this.changeStoreSure(goodsId, inOrganId, billOrganId, nums);


                Boolean isTrigger = updateStoreBillEntryState(nums, entryId, quantity); //更新当前分录状态
                if (isTrigger) {
                    this.updateStoreBillState(billId);
                }


            }
        }


        return true;
    }

    /**
     * 遍历指定单据下的所有分录判断是否都是完成复核状态
     * 如果是则指定单据的状态变更为已经完成
     * 否则 不做操作
     *
     * @param billId
     * @author 李珂
     */
    private void updateStoreBillState(String billId) {
        String sql = "select   count(1) as counts\n" +
                "         from bill_store_entry bse\n" +
                "     where  bse.owner_id  = ?\n" +
                "       and  bse.state = 0";
        Long counts = ((BigInteger) storeBillEntryDao.findUniqueBySQL(sql, billId).get("counts")).longValue();
        if (counts == 0) {//说明该单据下的所有分录已经完成复核该单据状态变更为生效->完成
            String updataSql = "update bill_store set state = 1 where id = ?";
            SQLQuery sqlQuery = storeBillEntryDao.getSession().createSQLQuery(updataSql);
            sqlQuery.setString(0, billId);
            sqlQuery.executeUpdate();

            //TODO 若有原始单据 则更改原始单据状态为完成
            this.updateOriginalBill(billId);
        }
    }

    /**
     * 更新分录状态
     *
     * @param numbers  已复核数量
     * @param entryId  复核分录ID
     * @param quantity 分录需要复核数量
     * @author 李珂
     */
    private Boolean updateStoreBillEntryState(Double numbers, String entryId, Double quantity) {
        Session csession = storeBillEntryDao.getSession();
        SQLQuery sqlQuery;
        String updateSql = "";
        if (quantity.compareTo(numbers) == 0) {//如果复核数量等于需要复核数量的话说明该分录的状态为待复核->完成
            updateSql = "update bill_store_entry set state = 1,quantity = 0,checked = checked +? where id  = ?";
            sqlQuery = csession.createSQLQuery(updateSql);
            sqlQuery.setDouble(0, numbers);
            sqlQuery.setString(1, entryId);
            sqlQuery.executeUpdate();
            return true;//只有该单据分录被设置成已经复核，该单据分录的主单据才有可能变为完整状态因此才会触发更新该单据分录的更新逻辑
        } else {
            updateSql = "update bill_store_entry set quantity = ?,checked =checked + ? where id  = ?";
            sqlQuery = csession.createSQLQuery(updateSql);
            sqlQuery.setDouble(0, quantity - numbers);
            sqlQuery.setDouble(1, numbers);
            sqlQuery.setString(2, entryId);
            sqlQuery.executeUpdate();
            return false;

        }
    }

    /**
     * 如果是定向入库
     *
     * @param goodsId        商品ID
     * @param inOrganId      收货仓库ID
     * @param primaryOrganId 复核单据的所属机构ID
     * @param numbers        待复核数量
     * @author 李珂
     */
    private void changeStoreSure(String goodsId, String inOrganId, String primaryOrganId, Double numbers) {
        if (ObjectUtils.isEmpty(numbers)) {
            throw new RuntimeException("请填写正确的商品数量");
        }

        //判断当前分录的仓库是否与入库仓库一致
        boolean isSameOrgan = primaryOrganId.equals(inOrganId);


        Date currentDate = new Date();
        String today = Convertor.formatDate(currentDate, "yyyy-MM-dd");
        /**
         * 首先查询当前仓库当天是不是有该商品
         */
        Boolean flag = isHasToday(goodsId, inOrganId, today);

        if (isSameOrgan) { //两个仓库是否一样
            if (!flag) {
                this.insertStoreInReview(inOrganId, goodsId, numbers);
            } else {
                this.updateStore(numbers, today, inOrganId, goodsId);
            }
        } else {
            /**
             *  查询分录所在仓库当天是不是有商品
             */
            Boolean flag2 = isHasToday(goodsId, primaryOrganId, today);

            //首先操作分录所在仓库
            if (!flag) {
                this.insertStoreInDiffOrgan(inOrganId, goodsId, numbers, false);
            } else {
                this.updateStoreInDiffOrgan(inOrganId, goodsId, numbers, false, today);
            }

            //其次操作新仓库
            if (!flag2) {
                this.insertStoreInDiffOrgan(primaryOrganId, goodsId, numbers*-1, true);
            } else {
                this.updateStoreInDiffOrgan(primaryOrganId, goodsId, numbers, true, today);
            }
        }


    }

    /**
     * 复核仓库与分录所在仓库不一样时 商品库存的修改操作
     *
     * @param organId
     * @param goodsId
     * @param numbers
     * @param isEntryOrgan
     */
    private void updateStoreInDiffOrgan(String organId, String goodsId, Double numbers, boolean isEntryOrgan, String today) {
        Session csession = storeBillEntryDao.getSession();
        String updateSql = "";
        SQLQuery sqlQuery = null;
        if (isEntryOrgan) {
            updateSql = "update goods_store   set " +
                    "in_transit = in_transit-? " +
                    "where to_char(create_time,'yyyy-mm-dd') =?" +
                    "\n and organ_id = ?" +
                    "\n and goods_id = ?";
        } else {
            updateSql = "update goods_store   set " +
                    "store_num = store_num +? " +
                    "where to_char(create_time,'yyyy-mm-dd') =?" +
                    "\n and organ_id = ?" +
                    "\n and goods_id = ?";
        }
        sqlQuery = csession.createSQLQuery(updateSql);
        sqlQuery.setDouble(0, numbers);
        sqlQuery.setString(1, today);
        sqlQuery.setString(2, organId);
        sqlQuery.setString(3, goodsId);
        sqlQuery.executeUpdate();
    }

    /**
     * 复核仓库与分录所在仓库不一样时 商品库存的插入操作
     *
     * @param organId
     * @param goodsId
     * @param numbers
     * @param isEntryOrgan 是否为分录所在仓库
     */
    private void insertStoreInDiffOrgan(String organId, String goodsId, Double numbers, boolean isEntryOrgan) {
        Session csession = storeBillEntryDao.getSession();
        SQLQuery sqlQuery = null;
        String iSql = null;
        if (!isEntryOrgan) {
            iSql = "insert into goods_store (organ_id,goods_id,store_num) VALUES (?,?,?)";
        } else {
            iSql = "insert into goods_store (organ_id,goods_id,in_transit) VALUES (?,?,?)";
        }
        sqlQuery = csession.createSQLQuery(iSql);
        sqlQuery.setString(0, organId);
        sqlQuery.setString(1, goodsId);
        sqlQuery.setDouble(2, numbers);

        sqlQuery.executeUpdate();
    }

    /**
     * 执行更新操作
     *
     * @param numbers 复核数量
     * @param today   当前日期
     * @author 李珂
     */
    private void updateStore(Double numbers, String today, String organId, String goodsId) {
        Session csession = storeBillEntryDao.getSession();
        SQLQuery sqlQuery = null;
        String updateSql = "update goods_store   set store_num = store_num +?" +
                ",in_transit = in_transit-? " +
                "where to_char(create_time,'yyyy-mm-dd') =?" +
                "\n and organ_id = ?" +
                "\n and goods_id = ?";
        sqlQuery = csession.createSQLQuery(updateSql);
        sqlQuery.setDouble(0, numbers);
        sqlQuery.setDouble(1, numbers);
        sqlQuery.setString(2, today);
        sqlQuery.setString(3, organId);
        sqlQuery.setString(4, goodsId);
        sqlQuery.executeUpdate();
    }

    /**
     * 更新在途
     *
     * @param numbers
     * @param today
     * @param organId
     * @param goodsId
     */
    private void updateInTransit(Double numbers, String today, String organId, String goodsId) {
        Session csession = storeBillEntryDao.getSession();
        SQLQuery sqlQuery = null;
        String updateSql = "update goods_store  set in_transit = in_transit+? " +
                "where to_char(create_time,'yyyy-mm-dd') =?" +
                "\n and organ_id = ?" +
                "\n and goods_id = ?";
        sqlQuery = csession.createSQLQuery(updateSql);
        sqlQuery.setDouble(0, numbers);
        sqlQuery.setString(1, today);
        sqlQuery.setString(2, organId);
        sqlQuery.setString(3, goodsId);
        sqlQuery.executeUpdate();
    }

    /**
     * 更新冻结
     *
     * @param numbers
     * @param today
     * @param organId
     * @param goodsId
     */
    private void updateFreeUp(Double numbers, String today, String organId, String goodsId) {
        Session csession = storeBillEntryDao.getSession();
        SQLQuery sqlQuery = null;
        String updateSql = "update goods_store   set freeze_up = freeze_up+? " +
                "where to_char(create_time,'yyyy-mm-dd') =?" +
                "\n and organ_id = ?" +
                "\n and goods_id = ?";
        sqlQuery = csession.createSQLQuery(updateSql);
        sqlQuery.setDouble(0, numbers);
        sqlQuery.setString(1, today);
        sqlQuery.setString(2, organId);
        sqlQuery.setString(3, goodsId);
        sqlQuery.executeUpdate();
    }

    /**
     * 执行仓库保存操作
     *
     * @param primaryOrganId//收货仓库
     * @param goodsId
     * @param numbers
     */
    private void insertStore(String primaryOrganId, String goodsId, Double numbers) {
        Session csession = storeBillEntryDao.getSession();
        SQLQuery sqlQuery = null;
        String iSql = "insert into goods_store (organ_id,goods_id,in_transit) VALUES (?,?,?)";
        sqlQuery = csession.createSQLQuery(iSql);
        sqlQuery.setString(0, primaryOrganId);
        sqlQuery.setString(1, goodsId);
        sqlQuery.setDouble(2, numbers);

        sqlQuery.executeUpdate();
    }

    /**
     * 判断当前是否有数据入库
     *
     * @param goodsId 商品ID
     * @param storeId 商品仓库
     * @param today   当天日期
     * @return
     * @author 李珂
     */
    private Boolean isHasToday(String goodsId, String storeId, String today) {
        String sql = "select count(1) as counts from goods_store gs where gs.goods_id = ?\n" +
                "                               and gs.organ_id = ?\n" +
                "                               and to_char(gs.create_time,'yyyy-mm-dd') = ?";

        Map<String, Object> isHasToday = storeBillEntryDao.findUniqueBySQL(sql, goodsId, storeId, today);
        BigInteger counts1 = (BigInteger) isHasToday.get("counts");
        Long counts = counts1.longValue();
        if (counts > 0) {
            return true;
        }
        return false;
    }

    /**
     * 未复核的单据
     *
     * @param organIds 当前用户的可视机构
     * @param rows
     * @param startIdx @return
     * @param param
     */
    public List<Map<String, Object>> getNoCompleteBill(List<String> organIds, Integer rows, int startIdx, String param) {
        param = StringUtils.trimToEmpty(param);
        String oids = StringUtils.join(organIds, "','");
        String sql = "select bs.id                 --单据ID\n" +
                "                              ,bs.biz_type    btype  --单据类型\n" +
                "                              ,bs.create_time ctime  --创建时间\n" +
                "                              ,borgan.name    oname  --机构名称\n" +
                "                              ,borgan.id    oid  --机构id\n" +
                "                              ,bs.remark             --备注\n" +
                "                              ,bs.salebill_id sid  --销售或采购单号\n" +
                "                              ,bs.handername hname --经手人\n" +
                "                              ,buser.name    uname --制单人\n" +
                "                              ,bs.sn               --单据号\n" +
                "                              ,bs.state               --单据状态\n" +
                "                              ,bs.biz_bill_sn               --原始单据单号\n" +
                "                               from bill_store bs,\n" +
                "                                    bsf_users buser,\n" +
                "                                    bsf_organ borgan\n" +
                "                            where bs.organ_id in ('" + oids + "')\n" +
                "                                  and bs.state = 0\n" +
                "                                  and bs.creator_id = buser.id\n" +
                "                                  and bs.organ_id = borgan.id\n" +
                "                                  AND exists(SELECT * FROM bill_store_entry bse WHERE bse.owner_id = bs.id and bse.state <> -1)\n";
        if (StringUtils.isNotBlank(param)) {
            sql += "AND (bs.biz_bill_sn like '%" + param + "%' OR bs.sn like '%" + param + "%')\n";
        }
        sql += "                                  order by bs.create_time desc";
        List<Map<String, Object>> noCompleteBill = storeBillEntryDao.findBySQL(sql, startIdx, rows);
        return noCompleteBill;
    }

    public Long getNoCompleteBillCount(List<String> organIds, String param) {
        param = StringUtils.trimToEmpty(param);
        String oids = StringUtils.join(organIds, "','");
        String countSql = "select count(1) as counts\n" +
                "from bill_store bs,\n" +
                "  bsf_users buser,\n" +
                "  bsf_organ borgan\n" +
                "where bs.organ_id in ('" + oids + "')\n" +
                "and bs.state = 0\n" +
                "and bs.creator_id = buser.id\n" +
                "and bs.organ_id = borgan.id\n" +
                "        AND exists(SELECT * FROM bill_store_entry bse WHERE bse.owner_id = bs.id and bse.state <> -1)\n";
        if (StringUtils.isNotBlank(param)) {
            countSql += "AND (bs.biz_bill_sn like '%" + param + "%' OR bs.sn like '%" + param + "%')\n";
        }
        BigInteger count = (BigInteger) storeBillEntryDao.findUniqueBySQL(countSql).get("counts");
        return count.longValue();
    }

    public Long getStoreBillEntrySizeBySql(String id) {
        String sql = "select   count(1) as counts\n" +
                "         from bill_store_entry bse \n" +
                "         where bse.owner_id = ?\n" +
                "           and bse.state>=0";
        BigInteger counts = (BigInteger) storeBillEntryDao.findUniqueBySQL(sql, id).get("counts");
        return counts.longValue();
    }

    public List<Map<String, Object>> getStoreBillEntryBySql(String id, int startIdx, Integer rows) {
        String sql = "    select\n" +
                "         bse.id\n" +
                "        ,good.name\n" +
                "        ,ba.file_name as picturename\n" +
                "        ,bse.quantity  --在途数量\n" +
                "        ,bse.checked   --已复核数量\n" +
                "        ,bse.price     --价格\n" +
                "        ,bse.amount    --总数\n" +
                "         from bill_store_entry bse\n" +
                "             ,goods good" +
                "         left join goods_pictures gp on gp.goods_id=good.id left join bsf_attachment ba on gp.picture_id=ba.id\n" +
                "         where bse.owner_id = ?\n" +
                "           and bse.state>=0\n" +
                "           and bse.goods_id = good.id";
        List<Map<String, Object>> billEntrys = storeBillEntryDao.findBySQL(sql, startIdx, rows, id);
        return billEntrys;
    }

    /**
     * 现在开始是出库复核逻辑
     *
     * @param entryIds
     * @param outOrganId
     * @param numbers
     * @return
     */
    public Boolean executedByEntryIdOut(List<String> entryIds, String outOrganId, List<Double> numbers) {

        String ids = StringUtils.join(entryIds, "','");
        String sql = "select\n" +
                "   be.owner_id as billid  \n" +
                "  ,be.goods_id as gid    \n" +
                "  ,be.quantity  \n" +
                "  ,be.store_id as sid   " +
                "  ,be.id as entryid  " +
                "  ,bs.organ_id as oid   " +
                "  ,be.state     \n" +
                "\n" +
                "from    bill_store_entry be,\n" +
                "              bill_store bs\n" +
                "where\n" +
                "       be.id in('" + ids + "') \n" +
                "       and be.state = 0  " +
                "       and be.owner_id = bs.id\n";

        //得到当前机构下
        List<Map<String, Object>> storeBillEntrys = storeBillEntryDao.findBySQL(sql);
        if (!ObjectUtils.isEmpty(storeBillEntrys)) {
            for (int i = 0; i < storeBillEntrys.size(); i++) {
                Double nums = numbers.get(i);
                //for(Map<String,Object> billEntry:storeBillEntrys){
                Map<String, Object> billEntry = storeBillEntrys.get(i);
                String goodsId = (String) billEntry.get("gid");
                String entryId = (String) billEntry.get("entryid");
                BigDecimal quantity1 = (BigDecimal) billEntry.get("quantity");
                Double quantity = quantity1.doubleValue();
                String billOrganId = (String) billEntry.get("oid");
                String billId = (String) billEntry.get("billid");

                this.changeStoreSureOut(goodsId, outOrganId, billOrganId, nums);


                Boolean isTrigger = updateStoreBillEntryState(nums, entryId, quantity); //更新当前分录状态
                if (isTrigger) {
                    this.updateStoreBillState(billId);
                }


            }
        }


        return true;

    }

    private void changeStoreSureOut(String goodsId, String outOrganId, String billOrganId, Double nums) {
        if (ObjectUtils.isEmpty(nums)) {
            throw new RuntimeException("请填写正确的商品数量");
        }

        boolean isSameOrgan = billOrganId.equals(outOrganId);

        Date currentDate = new Date();
        String today = Convertor.formatDate(currentDate, "yyyy-MM-dd");
        /**
         * 首先查询当前仓库当天是不是有该商品
         */
        Boolean flag = isHasToday(goodsId, outOrganId, today);

        if (isSameOrgan) {
            if (!flag) {//说明当前还没有对指定商品的操作因此做插入操作

//            this.outStore(outOrganId, goodsId, nums);
                this.insertStoreOutReview(outOrganId, goodsId, nums);
            } else {

                this.updateStoreOut(nums, today, outOrganId, goodsId);

            }
        } else {
            /**
             * 首先查询当前仓库当天是不是有该商品
             */
            Boolean flag2 = isHasToday(goodsId, billOrganId, today);

            if (!flag) {
                this.outStoreDiffOrgan(outOrganId, goodsId, nums*-1, false);
            } else {
                this.updateOutStoreDiffOrgan(outOrganId,goodsId,nums,false,today);
            }

            if (!flag2) {
                this.outStoreDiffOrgan(billOrganId, goodsId, nums * -1, true);
            } else {
                this.updateOutStoreDiffOrgan(billOrganId,goodsId,nums,true,today);
            }
        }
    }

    /**
     * 复核出库  两个仓库不一致  修改操作
     *
     * @param organId
     * @param goodsId
     * @param numbers
     * @param isEntryOrgan
     * @param today
     */
    private void updateOutStoreDiffOrgan(String organId, String goodsId, Double numbers, boolean isEntryOrgan, String today) {
        Session csession = storeBillEntryDao.getSession();
        SQLQuery sqlQuery = null;
        String updateSql = "";
        // store_num = store_num-?
        if (isEntryOrgan){
            updateSql = "update goods_store  set " +
                    "freeze_up = freeze_up-? " +
                    "where to_char(create_time,'yyyy-mm-dd') =?" +
                    "\n and organ_id = ?" +
                    "\n and goods_id = ?";
        }
        else {
            updateSql = "update goods_store  set " +
                    "store_num = store_num-? " +
                    "where to_char(create_time,'yyyy-mm-dd') =?" +
                    "\n and organ_id = ?" +
                    "\n and goods_id = ?";
        }
        sqlQuery = csession.createSQLQuery(updateSql);
        sqlQuery.setDouble(0, numbers);
        sqlQuery.setString(1, today);
        sqlQuery.setString(2, organId);
        sqlQuery.setString(3, goodsId);
        sqlQuery.executeUpdate();
    }

    /**
     * 复核出库  两个仓库不一致  插入操作
     *
     * @param outOrganId
     * @param goodsId
     * @param nums
     * @param isEntryOrgan
     */
    private void outStoreDiffOrgan(String outOrganId, String goodsId, Double nums, boolean isEntryOrgan) {
        Session csession = storeBillEntryDao.getSession();
        SQLQuery sqlQuery = null;
        String iSql = "";
        if (isEntryOrgan) {
            iSql = "insert into goods_store (organ_id,goods_id,freeze_up) VALUES (?,?,?)";
        } else {
            iSql = "insert into goods_store (organ_id,goods_id,store_num) VALUES (?,?,?)";
        }
        sqlQuery = csession.createSQLQuery(iSql);
        sqlQuery.setString(0, outOrganId);
        sqlQuery.setString(1, goodsId);
        sqlQuery.setDouble(2, nums);

        sqlQuery.executeUpdate();
    }

    private void outStore(String outOrganId, String goodsId, Double nums) {
        Session csession = storeBillEntryDao.getSession();
        SQLQuery sqlQuery = null;
        String iSql = "insert into goods_store (organ_id,goods_id,freeze_up) VALUES (?,?,?)";
        sqlQuery = csession.createSQLQuery(iSql);
        sqlQuery.setString(0, outOrganId);
        sqlQuery.setString(1, goodsId);
        sqlQuery.setDouble(2, nums);

        sqlQuery.executeUpdate();
    }

    private void updateStoreOut(Double numbers, String today, String organId, String goodsId) {
        Session csession = storeBillEntryDao.getSession();
        SQLQuery sqlQuery = null;
        String updateSql = "update goods_store  set store_num = store_num-?" +
                ",freeze_up = freeze_up-? " +
                "where to_char(create_time,'yyyy-mm-dd') =?" +
                "\n and organ_id = ?" +
                "\n and goods_id = ?";
        sqlQuery = csession.createSQLQuery(updateSql);
        sqlQuery.setDouble(0, numbers);
        sqlQuery.setDouble(1, numbers);
        sqlQuery.setString(2, today);
        sqlQuery.setString(3, organId);
        sqlQuery.setString(4, goodsId);
        sqlQuery.executeUpdate();
    }

    /**
     * 复核出库-->当天没有库存操作
     *
     * @param outOrganId
     * @param goodsId
     * @param nums
     */
    private void insertStoreOutReview(String outOrganId, String goodsId, Double nums) {
        Session csession = storeBillEntryDao.getSession();
        SQLQuery sqlQuery = null;
        String iSql = "insert into goods_store (organ_id,goods_id,store_num,freeze_up) VALUES (?,?,?,?)";
        sqlQuery = csession.createSQLQuery(iSql);
        sqlQuery.setString(0, outOrganId);
        sqlQuery.setString(1, goodsId);
        sqlQuery.setDouble(2, nums * -1);
        sqlQuery.setDouble(3, nums * -1);

        sqlQuery.executeUpdate();
    }

    /**
     * 复核入库-->当天没有库存操作
     *
     * @param inOrganId
     * @param goodsId
     * @param nums
     */
    private void insertStoreInReview(String inOrganId, String goodsId, Double nums) {
        Session csession = storeBillEntryDao.getSession();
        SQLQuery sqlQuery = null;
        String iSql = "insert into goods_store (organ_id,goods_id,store_num,in_transit) VALUES (?,?,?,?)";
        sqlQuery = csession.createSQLQuery(iSql);
        sqlQuery.setString(0, inOrganId);
        sqlQuery.setString(1, goodsId);
        sqlQuery.setDouble(2, nums);
        sqlQuery.setDouble(3, nums * -1);

        sqlQuery.executeUpdate();
    }

    //////////////////////////////////////////////////////////
    //TODO 若有原始单据 则更改原始单据状态为完成
    private void updateOriginalBill(String storeBillId) {
        String sql = "SELECT bs.biz_bill_id,bs.biz_type FROM bill_store bs WHERE bs.id=?";
        List<Map<String, Object>> bySQL = this.storeBillDao.findBySQL(sql, storeBillId);
        if (bySQL != null && bySQL.size() == 1) {
            Map<String, Object> billStore = bySQL.get(0);
            String biz_bill_id = (String) billStore.get("biz_bill_id");
            short biz_type = (short) billStore.get("biz_type");
            if (biz_type == 2) {//原单据为采购单
                this.purchaseBillService.updateState(biz_bill_id, 2);
            } else if (biz_type == 3 || biz_type == -3) {
                boolean allotStoreComplete = this.isAllotStoreComplete(biz_bill_id);
                if (allotStoreComplete) {
                    this.allotBillServiceImpl.updateState(biz_bill_id, 1);
                }
            }
        } else {
            throw new RuntimeException("单据异常");
        }
    }

    /**
     * 判断由某条调拨单生成的出入库单据是否都完成
     *
     * @param allotId
     */
    private boolean isAllotStoreComplete(String allotId) {
        String sql = "SELECT bs.id,bs.state FROM bill_store bs WHERE bs.biz_bill_id = ?";
        List<Map<String, Object>> bySQL = this.storeBillDao.findBySQL(sql, allotId);
        if (bySQL != null && bySQL.size() == 2) {
            for (Map map : bySQL) {
                Short state = (Short) map.get("state");
                if (state.intValue() != 1) {
                    return false;
                }
            }
            return true;
        } else {
            throw new RuntimeException("单据异常");
        }
    }
}











